package com.seanzx.dp.condition;

import com.seanzx.common.Lists;
import com.seanzx.dp.common.Consts;
import com.seanzx.dp.entity.DataSelectEntity;
import com.seanzx.dp.ProcessorController;
import com.seanzx.dp.entity.Column;
import com.seanzx.dp.memory.TableBuffer;

import java.util.List;

/**
 * The results of different branches at the same level take or,
 * and the results of different levels of the same branch take and
 * For example, the result of the tree below is  (a || b) && x
 *    x
 *  /   \
 * a     b
 */
public class ConditionTree {
    private final List<Column> columns;
    private final ConditionNode root;
    private static ProcessorController processorController = ProcessorController.get();


    public ConditionTree(String databaseName, String tableName) {
        this.columns = TableBuffer.getTable(databaseName, tableName).get().getColumns();
        root = ConditionNode.rootNode();
    }

    public boolean test(List<String> values) {
        return root.test(columns, values);
    }

    public ConditionNode getRoot() {
        return root;
    }

    public void add(ConditionNode node) {
        root.and(node);
    }

    public static void main(String[] args) {
        ConditionTree tree = new ConditionTree("information_schema", "COLUMNS");

        ConditionNode node1 = new ConditionNode("TABLE_NAME", ConditionType.EQUALS, Lists.of("TABLES"));
        node1.and(new ConditionNode("COLUMN_INDEX", ConditionType.SMALLER, Lists.of("1")));
        tree.getRoot().and(node1);

        ConditionNode node2 = new ConditionNode("TABLE_NAME", ConditionType.EQUALS, Lists.of("COLUMNS"));
        node2.and(new ConditionNode("COLUMN_INDEX", ConditionType.BIGGER, Lists.of("1")));
        node1.or(node2);

        DataSelectEntity entity = new DataSelectEntity();
        entity.setDatabaseName(Consts.INFORMATION_SCHEMA);
        entity.setTableName("COLUMNS");
        for (List<String> datum : ProcessorController.get().select(entity).getData()) {
            if (tree.test(datum)) {
                System.out.println(datum);
            }
        }
    }
}
